﻿using System;
using System.IO;
using System.Collections.Generic;
using UnityEngine;

public class FileHelper
{
    public static string ConvertArchName(LuaArchType arch, string name)
    {
        switch (arch)
        {
            case LuaArchType.BIT_32:
                name += "_32";
                break;
            case LuaArchType.BIT_64:
                name += "_64";
                break;
            default:
                break;
        }

        return name;
    }

    public static string GetFullPath(string path)
    {
        bool addFileHead = true;
#if UNITY_ANDROID && !UNITY_EDITOR
        // 如果是读取apk里的资源,不需要加file:///,其它情况都要加
        if (path.Contains (Application.streamingAssetsPath)) {
            addFileHead = false;
        }
#endif
        if (addFileHead)
        {
            path = string.Format("file:///{0}", path);
        }

        return path;
    }

    public static string GetBundlePath(string path)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        path = path.Replace (Application.streamingAssetsPath, Application.dataPath + "!assets");
#endif
        return path;
    }

    public static void CreateDirectory(string path)
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
    }

    public static void DeleteDirectory(string path)
    {
        try
        {
            if (Directory.Exists(path))
            {
                DirectoryInfo di = new DirectoryInfo(path);
                di.Delete(true);
            }
        }
        catch (Exception e)
        {
            Debuger.LogError(e.Message);
        }
    }

    public static void DeleteFile(string path)
    {
        try
        {
            if (File.Exists(path))
            {
                File.Delete(path);
            }
        }
        catch (Exception e)
        {
            Debuger.LogError(e.Message);
        }
    }

    public static List<string> GetChildFiles(string path, string suffix = null, List<string> files = null)
    {
        if (files == null)
        {
            files = new List<string>();
        }

        if (!Directory.Exists(path))
        {
            return files;
        }

        AddFiles(path, suffix, files);

        return files;
    }

    public static List<string> GetAllChildFiles(string path, string suffix = null, List<string> files = null)
    {
        if (files == null)
        {
            files = new List<string>();
        }

        if (!Directory.Exists(path))
        {
            return files;
        }

        AddFiles(path, suffix, files);

        string[] temps = Directory.GetDirectories(path);
        for (int i = 0; i < temps.Length; ++i)
        {
            string dir = temps[i];
            GetAllChildFiles(dir, suffix, files);
        }

        return files;
    }

    public static void AddFiles(string path, string suffix, List<string> files)
    {
        string[] temps = Directory.GetFiles(path);
        for (int i = 0; i < temps.Length; ++i)
        {
            string file = temps[i];
            if (string.IsNullOrEmpty(suffix) || file.ToLower().EndsWith(suffix.ToLower()))
            {
                files.Add(file);
            }
        }
    }

    public static string GetURLFileSuffix(string url)
    {
        if (string.IsNullOrEmpty(url)) return string.Empty;
        int last = url.LastIndexOf(".");
        int end = url.IndexOf("?");
        if (end == -1)
        {
            end = url.Length;
        }
        else
        {
            last = url.IndexOf(".", 0, end);
        }

        string cut = url.Substring(last, end - last).Replace(".", "");
        return cut;
    }

    public static string GetURLFileName(string url)
    {
        if (string.IsNullOrEmpty(url)) return string.Empty;
        string re = "";
        int len = url.Length - 1;
        char[] arr = url.ToCharArray();
        while (len >= 0 && arr[len] != '/' && arr[len] != '\\')
            len = len - 1;
        //int sub = (url.Length - 1) - len;
        //int end=url.Length-sub;

        re = url.Substring(len + 1);
        int last = re.LastIndexOf(".");
        if (last == -1) last = re.Length;
        string cut = re.Substring(0, last);
        return cut;
    }

    public static string GetKeyURLFileName(string url)
    {
        if (string.IsNullOrEmpty(url)) return string.Empty;
        string re = "";
        int len = url.Length - 1;
        char[] arr = url.ToCharArray();
        while (len >= 0 && arr[len] != '/' && arr[len] != '\\')
        {
            len = len - 1;
        }

        re = url.Substring(len + 1);
        int last = re.LastIndexOf(".");
        if (last == -1) last = re.Length;
        string cut = re.Substring(0, last);
        cut = cut.Replace('.', '_');
        return cut;
    }

    public static string GetURLFullFileName(string url)
    {
        if (string.IsNullOrEmpty(url)) return string.Empty;
        string re = "";
        int len = url.Length - 1;
        char[] arr = url.ToCharArray();
        while (len >= 0 && arr[len] != '/' && arr[len] != '\\')
        {
            len = len - 1;
        }

        re = url.Substring(len + 1);
        return re;
    }

    public static string ReadTextFromFile(string path, string defaultValue = "")
    {
        string ret = defaultValue;

        FileInfo fi = new FileInfo(path);
        if (fi.Exists)
        {
            StreamReader reader = fi.OpenText();
            ret = reader.ReadToEnd();
            reader.Close();
            reader.Dispose();
        }

        return ret;
    }

    public static void SaveTextToFile(string text, string path)
    {
        CreateDirectoryFromFile(path);
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text);

        SaveBytesToFile(bytes, path);
    }

    public static byte[] ReadBytesFromFile(string path)
    {
        byte[] bytes = null;

        bool useFileReader = true;
#if UNITY_ANDROID && !UNITY_EDITOR
        // 如果是读apk包里的资源,使用Android帮助库加载
        if (path.Contains (Application.streamingAssetsPath)) {
            useFileReader = false;

            path = path.Replace (Application.streamingAssetsPath + "/", "");
			bytes = AndroidHelper.FileHelper.CallStatic<byte[]> ("LoadFile", path);
        }
#endif
        if (useFileReader && File.Exists(path))
        {
            bytes = File.ReadAllBytes(path);
        }

        return bytes;
    }

    //copy assets目录下的文件到指定路径，仅限Android使用
    public static bool CopyAssetsFileTo(string strFrom, string strTo)
    {
        bool ret = true;
#if UNITY_ANDROID && !UNITY_EDITOR
		strFrom = strFrom.Replace (Application.streamingAssetsPath + "/", "");
		ret = AndroidHelper.FileHelper.CallStatic<bool>("CopyFileTo", strFrom, strTo);
#endif

        return ret;
    }

    public static void SaveBytesToFile(byte[] bytes, string path)
    {
        CreateDirectoryFromFile(path);

        try
        {
            Stream stream = File.Open(path, FileMode.Create);
            stream.Write(bytes, 0, bytes.Length);
            stream.Close();
        }
        catch (Exception e)
        {
            Debuger.LogError(e.Message);
        }
    }

    public static void CopyFileTo(string pathSource, string pathDest)
    {
        DeleteFile(pathDest);
        CreateDirectoryFromFile(pathDest);
        File.Copy(pathSource, pathDest);
    }

    public static void CreateDirectoryFromFile(string path)
    {
        path = path.Replace("\\", "/");
        int index = path.LastIndexOf("/");
        string dir = path.Substring(0, index);

        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
    }

    public delegate bool CopyFilter(string file);
    public static void CopyDirectory(string sourcePath, string destinationPath, string suffix = "", CopyFilter onFilter = null)
    {
        if (onFilter != null && onFilter(sourcePath))
        {
            return;
        }

        if (!Directory.Exists(destinationPath))
        {
            Directory.CreateDirectory(destinationPath);
        }

        foreach (string file in Directory.GetFileSystemEntries(sourcePath))
        {
            if (File.Exists(file))
            {
                FileInfo info = new FileInfo(file);
                if (string.IsNullOrEmpty(suffix) || file.ToLower().EndsWith(suffix.ToLower()))
                {
                    string destName = Path.Combine(destinationPath, info.Name);
                    if (!(onFilter != null && onFilter(file)))
                    {
                        File.Copy(file, destName);
                    }
                }
            }

            if (Directory.Exists(file))
            {
                DirectoryInfo info = new DirectoryInfo(file);
                string destName = Path.Combine(destinationPath, info.Name);
                CopyDirectory(file, destName, suffix, onFilter);
            }
        }
    }

    public static bool RenameDirectory(string pathSrc, string pathDst)
    {
        if (!Directory.Exists(pathSrc) || Directory.Exists(pathDst))
        {
            return false;
        }

        Directory.Move(pathSrc, pathDst);
        return true;
    }

    public static void DeleteFolder(string dir)
    {
        foreach (string d in Directory.GetFileSystemEntries(dir))
        {
            if (File.Exists(d))
            {
                FileInfo fi = new FileInfo(d);
                if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
                {
                    fi.Attributes = FileAttributes.Normal;
                }

                File.Delete(d);
            }
            else
            {
                DirectoryInfo d1 = new DirectoryInfo(d);
                if (d1.GetFiles().Length != 0)
                {
                    DeleteFolder(d1.FullName); //递归删除子文件夹
                }
                Directory.Delete(d);
            }
        }
    }

    public static long GetFileSize(string path)
    {
        System.IO.FileInfo info = new System.IO.FileInfo(path);
        return info.Length;
    }

    public static long GetDirectorySize(string path)
    {
        if (!Directory.Exists(path))
        {
            return 0;
        }

        long size = 0;

        DirectoryInfo info = new DirectoryInfo(path);
        foreach (FileInfo fi in info.GetFiles())
        {
            size += fi.Length;
        }

        foreach (DirectoryInfo di in info.GetDirectories())
        {
            size += GetDirectorySize(di.FullName);
        }
        return size;
    }
}